package com.sduonline.isdapp.service;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.sduonline.isdapp.jdbc.WebDao;
import com.sduonline.isdapp.model.Article;
import com.sduonline.isdapp.model.Web;

public class AutoService {

    private static ScheduledExecutorService scheduledThreadPool = null;
    private static ExecutorService cachedThreadPool = null;

	private WebDao wdao = new WebDao();
	private List<Web> webs = null;
	/**

	 * 初始化的最大线程池数目

	 */
	private static int MaxThread = 10;
	private static int MaxCycleVisitTime = 30;// 最大的访问完所有网站的一个周期的时间,单位min,默认30min


	public AutoService() {
		// 得到数据库中所有要爬取的网站


		if (webs == null) {
			webs = wdao.getAll();
		}
	}

	/**

	 * 遍历webenum，通过延迟逐个访问。

	 */
	public void start() {
		// 初始化线程池，线程池中线程数根据下列要使用线程的个数而定


		if (scheduledThreadPool == null) {
			scheduledThreadPool = Executors.newScheduledThreadPool(MaxThread);
		}

		System.out.println("the web's number is " + webs.size());
		if (webs.size() != 0) {
			int delay = MaxCycleVisitTime / webs.size();
			int start = delay;// 使线程每隔delay时间便启动一次

			for (Web web : webs) {
				if (web != null && web.getInterface_url() != null) {
					visitWebs(web, start);
					start += delay;
				}
			}
		}

	}

	public void visitArticlesWithinTime(final String st, final String et) {

		if (cachedThreadPool == null) {
			cachedThreadPool = Executors.newCachedThreadPool();
		}

		// 初始化线程池，线程池中线程数根据下列要使用线程的个数而定


		if (webs.size() != 0) {
			int delay = MaxCycleVisitTime / webs.size();
			for (final Web web : webs) {
				if (web != null && web.getInterface_url() != null) {
					Runnable r = new Runnable() {
						// 每个run方法一旦初始化，那么整个周期的过程中，都一直使用同一个对象，即runnable中的全局变量是同一个。


						private CrawlerService cs = new CrawlerService();
						private List<Article> lastArticles = null;

						@Override
						public void run() {
							List<Article> articles = cs.execute(web, st, et);

							// 只有当最新取出的articles与上次有区别的时候，才会保存数据库


							if (articles != null) {
								if (!articles.equals(lastArticles)) {
									System.out.println("存在修改的数据，执行保存...");
									// 保存图片到articles中


									cs.save3Pic(articles);
									// 保存article类对象


									cs.saveArticle(articles);
								}
								lastArticles = articles;
							}

						}// end run

					};

					try {
						// 逐个启动线程


						Thread.sleep(delay);
						cachedThreadPool.execute(r);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				}// end if

			}// end for

		}

	}

	public void stop() {
		if (scheduledThreadPool != null) {
			scheduledThreadPool.shutdown();
		}
		if (cachedThreadPool != null) {
			cachedThreadPool.shutdown();
		}
	}

	/**

	 * 访问web,规定延迟delay，默认访问当天的数据

	 * 

	 * @param web

	 * @param delay

	 */
	private void visitWebs(final Web web, final int delay) {
		
		scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
			// 每个run方法一旦初始化，那么整个周期的过程中，都一直使用同一个对象，即runnable中的全局变量是同一个。


			private CrawlerService cs = new CrawlerService();
			private List<Article> lastArticles = null;

			@Override
			public void run() {
				try {
					List<Article> articles = cs.execute(web, System.currentTimeMillis() / 1000 + "", System.currentTimeMillis() / 1000 +"");

					// 只有当最新取出的articles与上次有区别的时候，才会保存数据库


					if (articles != null) {
						if (lastArticles==null||!articles.equals(lastArticles)) {
							System.out.println("存在修改的数据，执行保存...");
							// 保存图片到articles中


							cs.save3Pic(articles);
							// 保存article类对象


							cs.saveArticle(articles);
						} else {
							System.out.println("无需修改");
						}
						lastArticles = articles;
					} else {
						System.out.println("article is null ..");
					}

					articles = null;

				} catch (Exception e) {
					// TODO: handle exception


					System.out.println("scheduledThreadPool出错");
					e.printStackTrace();
				}
				
			}// end run


		}, delay, 30, TimeUnit.MINUTES);

		System.out.println("Thread start,url=" + web.getInterface_url() + ",delay=" + delay);
	}

	public static void main(String[] args) {
		new AutoService().visitArticlesWithinTime(System.currentTimeMillis() / 1000 - 24 * 60 * 60 * 5 + "",
				System.currentTimeMillis() / 1000 + "");
	}

}
